package com.easy.mq.config;

import com.easy.common.component.ExchangeType;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

//交换机类型：默认直接交换机：可以绑定多个队列   根据routingKey 进行匹配，把消息发送到每一个绑定的队列中，如果没有绑定指定的routingKey,
//消息会被丢弃
//扇形交换机：Fanout 可以绑定多个队列，将接受的消息直接派送到每一个绑定的队列，和routingKey没有关系
//主题交换机：可以绑定多个队列，根据routingKey中的内容（是否符合easy.*  或者easy.#），将消息派送到指定的队列中
// 这个routingKey可以由多个单词组成，多个单词之间用.隔开.
//头部交换机 headers  可以绑定多个队列 根据消息中头部的信息内容，将消息派送到指定的队列中（whereAll  和  whereAny）

//扇出交换机的速度最快
@Configuration//注解标注为 配置类
public class MQConfig {

    //创建消息队列A
    @Bean
    public Queue queueA(){
        return new Queue("queueA");
    }
    @Bean
    public Queue queueB(){
        return new Queue("queueB");
    }
    @Bean
    public Queue queueC(){
        return new Queue("queueC");
    }
    @Bean
    public Queue queueD(){
        return new Queue("queueD");
    }
    //创建消息队列SKQ
    @Bean
    public Queue queuesk(){
    return new Queue("SKQ");
    }
    //创建主题交换机
    @Bean
    public Binding binding_Topic_SKQ(@Qualifier("queuesk") Queue easyQueueB, TopicExchange topicExchange){
        return BindingBuilder.bind(easyQueueB).to(topicExchange).with("easy.#");
    }

    /**
     * 默认交换机
     * @return
     */
    //创建交换机
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(ExchangeType.directExchange.toString());
    }

    /**
     * 扇出交换机
     * @return
     */
    //创建扇出交换机
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(ExchangeType.fanoutExchange.toString());
    }

    /**
     * 主题交换器
     * @return
     */
    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange(ExchangeType.topicExchange.toString());
    }

    /**
     * 头交换机
     * @return
     */
    @Bean
    public HeadersExchange headersExchange() {
        return new HeadersExchange (ExchangeType.headersExchange.toString());
    }


    //默认交换机绑定
    @Bean
    public Binding binding_Direct_QueueA(@Qualifier("queueA") Queue easyQueueA, DirectExchange directExchange) {
        //设定的式默认交换机，必须明确指定绑定的路由键
        //若交换机未绑定任何队列，或消息的 Routing Key 未匹配任何已绑定的队列，消息会被交换机直接丢弃
        return BindingBuilder.bind(easyQueueA).to(directExchange).with("easyMQA");
    }

    @Bean
    public Binding binding_Direct_QueueC(@Qualifier("queueC") Queue easyQueueA, DirectExchange directExchange) {
        //设定的式默认交换机，必须明确指定绑定的路由键
        //若交换机未绑定任何队列，或消息的 Routing Key 未匹配任何已绑定的队列，消息会被交换机直接丢弃
        return BindingBuilder.bind(easyQueueA).to(directExchange).with("easyMQC");
    }

    //绑定扇出交换机
    @Bean
    public Binding binding_Fanout_QueueA(@Qualifier("queueA") Queue easyQueueA, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(easyQueueA).to(fanoutExchange);
    }

    @Bean
    public Binding binding_Fanout_QueueB(@Qualifier("queueB") Queue easyQueueB, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(easyQueueB).to(fanoutExchange);
    }

    @Bean
    public Binding binding_Topic_QueueA(@Qualifier("queueC") Queue easyQueueA, TopicExchange topicExchange){
        return BindingBuilder.bind(easyQueueA).to(topicExchange).with("easy.#");
    }
    @Bean
    public Binding binding_Topic_QueueB(@Qualifier("queueD") Queue easyQueueB, TopicExchange topicExchange){
        return BindingBuilder.bind(easyQueueB).to(topicExchange).with("easy.*");
    }

    //头部交换机
    @Bean
    public Binding binding_Header_All_QueueA(HeadersExchange headersExchange, @Qualifier("queueA") Queue easyQueueA) {
        Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("type", "message");
        headerMap.put("status", "active");
        return BindingBuilder.bind(easyQueueA)
                .to(headersExchange)
                .whereAll(headerMap) // x-match=all
                .match();
    }

    @Bean
    public Binding binding_Header_Any_QueueB(HeadersExchange headersExchange, @Qualifier("queueB") Queue easyQueueB) {
        Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("type", "message");
        headerMap.put("status", "active");
        return BindingBuilder.bind(easyQueueB)
                .to(headersExchange)
                .whereAny(headerMap) // x-match=any
                .match();
    }


    //下面应该放在不同的模块中
    //监听器        消费者  监听的队列是queueA
    @RabbitListener(queues = "queueA")
    public void listenterA(String message) {

        System.out.println("easyQueueA-------------"+message);
    }

    @RabbitListener(queues = "queueB")
    public void listenterB(String message) {

        System.out.println("easyQueueB-------------"+message);
    }

    @RabbitListener(queues = "queueC")
    public void listenterC(String message) {

        System.out.println("easyQueueC-------------"+message);
    }

    @RabbitListener(queues = "queueD")
    public void listenterD(String message) {

        System.out.println("easyQueueD-------------"+message);
    }


}

































